#pragma once

#include "TypedList.h"

template<class> class SuperTree;

static const u_int uFFileInfo_MAX_PATH = 256;
static const u_int uFFileInfo_MAX_NAME = 32;

enum FRIDGE_FILE_TYPES
{
	// File operations use these file types rather than passing paths and extensions around
	// Platforms are expected to save and load from the appropriate place (e.g. the Users directory on doze)

	FRIDGE_FILE_PRESET = 0,
	FRIDGE_FILE_TEMPLATE,
    FRIDGE_FILE_RESOURCE,
    FRIDGE_FILE_DATA,

	NUM_FRIDGE_FILE_TYPES
};

enum FRIDGE_TEMP_DIRECTORIES
{
    FRIDGE_DIR_TEMPORARY_ROOT = 0,
    FRIDGE_DIR_TEMPORARY_APP,
    FRIDGE_DIR_TEMPORARY_PRESET,
    FRIDGE_DIR_TEMPORARY_RESOURCES
};

enum FRIDGE_INTERNAL_FILES
{
    FRIDGE_INTERNAL_PRESET = 0,
    FRIDGE_INTERNAL_RESOURCE_LIST
};

//-------------------------------------------------------------------
//                          FFileInfo
//-------------------------------------------------------------------

class FFileInfo
{
	public:

		FFileInfo( );
		FFileInfo( const char* szFullPathAndName, const bool bIsDirectory );
		virtual ~FFileInfo();
		
		const char*		GetFullPathAndName	( )	const	{ return &m_szFullPathAndName[0]; }
		const char*		GetName				( ) const	{ return &m_szName[0]; }
		const char*		GetFullPath			( ) const	{ return 0; /* write me*/ }
		const char*		GetExtension		( ) const	{ return 0; /* write me*/ }
		bool			IsDirectory			( ) const	{ return m_bIsDirectory; }

	private:
		
		char m_szFullPathAndName[uFFileInfo_MAX_PATH];
		char m_szName[uFFileInfo_MAX_NAME];
		bool m_bIsDirectory;
		//char* m_szFilename;
		//char* m_szExtension;

		//StringHash xHash;
};

//-------------------------------------------------------------------
//                          FileTools
//-------------------------------------------------------------------

class FileTools
{
	public:

        static const char* szFRIDGE_INTERNAL_PRESET_FILE;
        static const char* szFRIDGE_INTERNAL_RESOURCE_LIST_FILE;

		static bool OpenPrompt( FRIDGE_FILE_TYPES eType, char* szOpenFile );
		static bool SavePrompt( FRIDGE_FILE_TYPES eType, char* szSaveFile );
		static void FindFiles ( SuperTree<FFileInfo>* pxFileList, FRIDGE_FILE_TYPES eType, const bool bRecursive = true );

		static void WriteStringToFile( const char* szString, FILE* pxFile );
		static void ReadStringFromFile( char*& szString, FILE* pxFile, bool bAllocateString );

        static bool MakeDirectory( FRIDGE_TEMP_DIRECTORIES eType );
        static void MakeTemporaryFile( FRIDGE_INTERNAL_FILES eType );
		
        static void WriteArchive( char* szArchiveDestination, char *pxFileName );

        static void GetTempDirectory( FRIDGE_TEMP_DIRECTORIES eType, char* szPath );
        static bool RemoveTempDirectory();
		static bool RenameDirectory( const char* szOldDirectory, const char* szNewDirectory );

		
		template<typename T> static void WriteToFile( const T& xVar, FILE* pxFile )
		{
			const u_int uTypeSize = sizeof( T );
			fwrite( &xVar, uTypeSize, 1, pxFile );
		}

		static void WriteToFile( const bool& bVar, FILE* pxFile )
		{
			// Deal with bool seperately since I don't think sizeof(bool) is necessarily the same on all platforms
			u_int uBool = static_cast<u_int>( bVar );
			WriteToFile<u_int>( uBool, pxFile );
		}

		template<typename T> static void ReadFromFile( T& xVar, FILE* pxFile )
		{
			const u_int uTypeSize = sizeof( T );
			fread( &xVar, uTypeSize, 1, pxFile );
		}

		static void ReadFromFile( bool& bVar, FILE* pxFile )
		{
			// Deal with bool seperately since I don't think sizeof(bool) is necessarily the same on all platforms
			const u_int uTypeSize = sizeof( u_int );
			u_int uTemp = 0;
			fread( &uTemp, uTypeSize, 1, pxFile );
			bVar = ( uTemp != 0 );
		}

	private:
			
		static void Platform_FindFiles( SuperTree<FFileInfo>* pxFileList, FRIDGE_FILE_TYPES eType, const bool bRecursive = true );
		static bool Platform_OpenPrompt( FRIDGE_FILE_TYPES eType, char* szOpenFile ); // NB: There is an assumption that this is a blocking call
		static bool Platform_SavePrompt( FRIDGE_FILE_TYPES eType, char* szSaveFile ); // NB: There is an assumption that this is a blocking call
			
        static bool Platform_MakeDirectory( const char* szPath );
		static bool Platform_RenameDirectory( const char* szOldDirectory, const char* szNewDirectory );
		static bool Platform_RemoveTempDirectory();

        static const char* Platform_GetTempDirectoryForType( FRIDGE_TEMP_DIRECTORIES eType);
};

//eof
